package com.eight.cloud.mybatisplus.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.MybatisUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
import com.eight.cloud.mybatisplus.entity.BaseEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.ognl.OgnlOps;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.SqlSession;

import java.io.Serializable;
import java.util.*;

/**
 * 特殊情况可供忽略逻辑删除使用
 * @InterfaceName: SuperMapper
 * @Author: TXC
 * @Date: 2024-12-18 17:43
 **/
public interface SuperMapper<T extends BaseEntity<T>> extends BaseMapper<T> {
    T selectRealById(Serializable id);
    List<T> selectRealBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList);
    void selectRealBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList, ResultHandler<T> resultHandler);
    List<T> selectRealList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    List<T> selectRealList(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    void selectRealList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper, ResultHandler<T> resultHandler);
    int realDelete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    default int realDeleteById(Serializable id) {
        return realDeleteById(id, true);
    }

    /**
     * 根据 ID 删除
     *
     * @param useFill 是否填充
     * @param obj      主键ID或实体
     * @since 3.5.7
     */
    default int realDeleteById(Object obj, boolean useFill) {
        Class<?> entityClass = GenericTypeUtils.resolveTypeArguments(getClass(), BaseMapper.class)[0];
        if (!entityClass.isAssignableFrom(obj.getClass()) && useFill) {
            TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
            if (tableInfo.isWithLogicDelete() && tableInfo.isWithUpdateFill()) {
                T instance = tableInfo.newInstance();
                tableInfo.setPropertyValue(instance, tableInfo.getKeyProperty(), OgnlOps.convertValue(obj, tableInfo.getKeyType()));
                return this.realDeleteById(instance);
            }
        }
        MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this);
        SqlSession sqlSession = mybatisMapperProxy.getSqlSession();
        return sqlSession.delete(mybatisMapperProxy.getMapperInterface().getName() + Constants.DOT + SqlMethod.DELETE_BY_ID.getMethod(), obj);
    }

    /**
     * 根据实体(ID)删除
     *
     * @param entity 实体对象
     * @since 3.4.4
     */
    int realDeleteById(@Param(Constants.ENTITY) T entity);


    /*default T selectByUuid(Serializable id) {
        return selectOne(Wrappers.<T>lambdaQuery().eq(T::getUuid, id));
    }

    default List<T> selectBatchByUuids(@Param(Constants.COLL) Collection<?> idList) {
        return selectList(Wrappers.<T>lambdaQuery().in(T::getUuid, idList));
    }

    default int updateByUuid(@Param(Constants.ENTITY) T entity) {
        return update(entity, Wrappers.<T>lambdaUpdate().eq(T::getUuid, entity.getUuid()));
    }

    default int removeByUuid(Serializable id) {
        return delete(Wrappers.<T>lambdaQuery().eq(T::getUuid, id));
    }

    default int deleteByUuids(@Param(Constants.COLL) Collection<?> idList) {
        return delete(Wrappers.<T>lambdaQuery().in(T::getUuid, idList));
    }*/
}
